package cs304.p3.library.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import cs304.p3.library.controller.LibrarianController;
import cs304.p3.library.domain.Book;
import cs304.p3.library.domain.BookCopy;
import cs304.p3.library.domain.Librarian;
import cs304.p3.library.framework.IoC;
import cs304.p3.library.util.FixedSizeNumberDocument;


@SuppressWarnings("serial")
public class LibrarianDialog extends JDialog{
	
	private MainFrame parent;
	private JTabbedPane tabbedPane;
	private JPanel addBookRootPanel, addBookPanel, addBookCopyPanel, checkOutRootPanel, checkOutPanel, popularRootPanel, popularPanel;
	private LibrarianController librarianController;
	private JTextField callField, isbnField, titleField, authorField, pubField, yearField, bookCopyCallField, subField, reportYearField, numBookField;
	private JTextField addAuthorsField, addSubjectsField;
	private JList authorList, subjectList, reportCheckoutList, reportPopularList;

	public LibrarianDialog(MainFrame frame, String title) {
		super(frame, title);
		parent = frame;
		setLayout(new BorderLayout());
		
		librarianController = IoC.resolve(LibrarianController.class);
		librarianController.setView(this);
		GridBagLayout gb = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		tabbedPane = new JTabbedPane();
		
		//Add book panel
		addBookRootPanel = new JPanel();
		addBookRootPanel.setLayout(new BorderLayout());
		addBookPanel = new JPanel();
		addBookPanel.setLayout(gb);
		addBookPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		addBookRootPanel.add(addBookPanel, BorderLayout.CENTER);
		
		JLabel callLabel, isbnLabel, titleLabel, authorLabel, pubLabel, yearLabel;
		callLabel = new JLabel("Call Number: ");
		isbnLabel = new JLabel("ISBN: ");
		titleLabel = new JLabel("Title: ");
		authorLabel = new JLabel("Author: ");
		pubLabel = new JLabel("Publisher: ");
		yearLabel = new JLabel("Year: ");
		callField = new JTextField(8);
		callField.setDocument(new FixedSizeNumberDocument(callField, 8));
		isbnField = new JTextField(8);
		isbnField.setDocument(new FixedSizeNumberDocument(isbnField, 8));
		titleField = new JTextField(8);
		authorField = new JTextField(8);
		pubField = new JTextField(8);
		yearField = new JTextField(8);
		yearField.setDocument(new FixedSizeNumberDocument(yearField, 4));
		//call#
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(callLabel, c);
		addBookPanel.add(callLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(callField, c);
		addBookPanel.add(callField);
		//ISBN
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(isbnLabel, c);
		addBookPanel.add(isbnLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(isbnField, c);
		addBookPanel.add(isbnField);
		//Title
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(titleLabel, c);
		addBookPanel.add(titleLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(titleField, c);
		addBookPanel.add(titleField);
		//Author
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(authorLabel, c);
		addBookPanel.add(authorLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(authorField, c);
		addBookPanel.add(authorField);
		//Publisher
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(pubLabel, c);
		addBookPanel.add(pubLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(pubField, c);
		addBookPanel.add(pubField);
		//Year
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(yearLabel, c);
		addBookPanel.add(yearLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(yearField, c);
		addBookPanel.add(yearField);
		//add book
		JButton addBookButton = new JButton("Add Book");
		addBookButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				if(yearField.getText().isEmpty()){
					IoC.displayUserInvalidInputMessage("Year cannot be empty");
				}else{
					Librarian lib = librarianController.getLibrarian();
					lib.setCallNumber(callField.getText());
					lib.setIsbn(isbnField.getText());
					lib.setMainAuthor(authorField.getText());
					lib.setPublisher(pubField.getText());
					lib.setTitle(titleField.getText());
					lib.setYear(Integer.parseInt(yearField.getText()));
					//Add all the sub-authors and all the subjects
					DefaultListModel model1 = (DefaultListModel) authorList.getModel();
					int size = model1.getSize();
					int i;
					for(i=0; i<size; i++) lib.addAuthor((String) model1.get(i));
					DefaultListModel model2 = (DefaultListModel) subjectList.getModel();
					size = model2.getSize();
					for(i=0; i<size; i++) lib.addSubject((String)model2.get(i));
					librarianController.performAddBookAction();
					parent.updateDBTables();
					model1.clear();
					model2.clear();
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(addBookButton, c);
		addBookPanel.add(addBookButton);
		
		
		//Author Lists
		JPanel authorPanel = new JPanel();
		authorPanel.setLayout(new BorderLayout());
		//Add list
		authorList = new JList(new DefaultListModel());
		authorList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
		authorPanel.add(new JScrollPane(authorList), BorderLayout.CENTER);
		//Control panel
		JPanel authorControlPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		authorControlPanel.setLayout(gb);
		authorControlPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		//Add Fields
		JLabel addAuthorsLabel = new JLabel("Author Name: ");
		addAuthorsField = new JTextField(8);
		//Add Author
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(addAuthorsLabel, c);
		authorControlPanel.add(addAuthorsLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(addAuthorsField, c);
		authorControlPanel.add(addAuthorsField);
		//Add button
		JButton addAuthor = new JButton("Add Author");
		addAuthor.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				DefaultListModel model = (DefaultListModel) authorList.getModel();
				if(addAuthorsField.getText().isEmpty()) IoC.displayUserInvalidInputMessage("Author Name cannot be empty!");
				else{
					model.addElement(addAuthorsField.getText());
					addAuthorsField.setText("");
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(addAuthor, c);
		authorControlPanel.add(addAuthor);
		//Remove button
		JButton removeAuthor = new JButton("Remove Author");
		removeAuthor.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				int index = authorList.getSelectedIndex();
				DefaultListModel model = (DefaultListModel) authorList.getModel();
				if(index > -1) model.remove(index);
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(removeAuthor, c);
		authorControlPanel.add(removeAuthor);
		//Add control
		authorPanel.add(authorControlPanel, BorderLayout.SOUTH);
		//Add to root panel
		addBookRootPanel.add(authorPanel, BorderLayout.WEST);
		
		//subject list
		JPanel subjectPanel = new JPanel();
		subjectPanel.setLayout(new BorderLayout());
		//Add list
		subjectList = new JList(new DefaultListModel());
		subjectList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
		subjectPanel.add(new JScrollPane(subjectList), BorderLayout.CENTER);
		//Control panel
		JPanel subjectControlPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		subjectControlPanel.setLayout(gb);
		subjectControlPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		//Add Fields
		JLabel addSubjectsLabel = new JLabel("Subject Name: ");
		addSubjectsField = new JTextField(8);
		//Add Author
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(addSubjectsLabel, c);
		subjectControlPanel.add(addSubjectsLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(addSubjectsField, c);
		subjectControlPanel.add(addSubjectsField);
		//Add button
		JButton addSubject = new JButton("Add Subject");
		addSubject.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				DefaultListModel model = (DefaultListModel) subjectList.getModel();
				if(addSubjectsField.getText().isEmpty()) IoC.displayUserInvalidInputMessage("Subject cannot be empty!");
				else {
					model.addElement(addSubjectsField.getText());
					addSubjectsField.setText("");
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(addSubject, c);
		subjectControlPanel.add(addSubject);
		//Remove button
		JButton removeSubject = new JButton("Remove Subject");
		removeSubject.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				int index = subjectList.getSelectedIndex();
				DefaultListModel model = (DefaultListModel) subjectList.getModel();
				if(index > -1) model.remove(index);
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(removeSubject, c);
		subjectControlPanel.add(removeSubject);
		//Add control
		subjectPanel.add(subjectControlPanel, BorderLayout.SOUTH);
		//Add to root panel
		addBookRootPanel.add(subjectPanel, BorderLayout.EAST);
		
		
		//Add book copy panel
		addBookCopyPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		addBookCopyPanel.setLayout(gb);
		addBookCopyPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JLabel bookCopyCallLabel;
		bookCopyCallLabel = new JLabel("Call Number: ");
		bookCopyCallField = new JTextField(8);
		bookCopyCallField.setDocument(new FixedSizeNumberDocument(bookCopyCallField, 8));
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(bookCopyCallLabel, c);
		addBookCopyPanel.add(bookCopyCallLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(bookCopyCallField, c);
		addBookCopyPanel.add(bookCopyCallField);
		JButton addBookCopyButton = new JButton("Add Book Copy");
		addBookCopyButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				if(bookCopyCallField.getText().isEmpty()){
					IoC.displayUserInvalidInputMessage("Call Number cannot be empty");
				}else{
					Librarian lib = librarianController.getLibrarian();
					lib.setCallNumber(bookCopyCallField.getText());
					librarianController.performAddBookCopyAction();
					parent.updateDBTables();
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(addBookCopyButton, c);
		addBookCopyPanel.add(addBookCopyButton);
		
		
		//check out report panel
		checkOutRootPanel = new JPanel();
		checkOutRootPanel.setLayout(new BorderLayout());
		//Add the list
		reportCheckoutList = new JList(new DefaultListModel());
		reportCheckoutList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
		JPanel reportCheckoutListPanel = new JPanel();
		reportCheckoutListPanel.setLayout(new BorderLayout());
		reportCheckoutListPanel.add(new JScrollPane(reportCheckoutList), BorderLayout.CENTER);
		checkOutRootPanel.add(reportCheckoutListPanel, BorderLayout.CENTER);
		//Check out Control
		checkOutPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		checkOutPanel.setLayout(gb);
		checkOutPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		//Subject
		JLabel subLabel = new JLabel("Subject (Optional): ");
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(subLabel, c);
		checkOutPanel.add(subLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		subField = new JTextField(8);
		gb.setConstraints(subField, c);
		checkOutPanel.add(subField);
		JButton reportCheckOut = new JButton("Report");
		reportCheckOut.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				Librarian lib = librarianController.getLibrarian();
				lib.setReportSubject(subField.getText());
				librarianController.performCheckOutReportAction();
				subField.setText("");
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(reportCheckOut, c);
		checkOutPanel.add(reportCheckOut);
		checkOutRootPanel.add(checkOutPanel, BorderLayout.WEST);
		
		
		//check out report panel
		popularRootPanel = new JPanel();
		popularRootPanel.setLayout(new BorderLayout());
		//Add the list
		reportPopularList = new JList(new DefaultListModel());
		reportPopularList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
		JPanel reportPopularListPanel = new JPanel();
		reportPopularListPanel.setLayout(new BorderLayout());
		reportPopularListPanel.add(new JScrollPane(reportPopularList), BorderLayout.CENTER);
		popularRootPanel.add(reportPopularListPanel, BorderLayout.CENTER);
		//popular report panel
		popularPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		popularPanel.setLayout(gb);
		popularPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JLabel reportYearLabel = new JLabel("Year: ");
		JLabel numBookLabel = new JLabel("Number of Books: ");
		reportYearField = new JTextField(8);
		reportYearField.setDocument(new FixedSizeNumberDocument(reportYearField, 4));
		numBookField = new JTextField(8);
		numBookField.setDocument(new FixedSizeNumberDocument(numBookField, 7));
		//year
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(reportYearLabel, c);
		popularPanel.add(reportYearLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(reportYearField, c);
		popularPanel.add(reportYearField);
		//n
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(numBookLabel, c);
		popularPanel.add(numBookLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(numBookField, c);
		popularPanel.add(numBookField);
		//report button
		JButton reportPopular = new JButton("Report");
		reportPopular.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				Librarian lib = librarianController.getLibrarian();
				String ry = reportYearField.getText();
				String rn = numBookField.getText();
				if(ry.isEmpty()){
					IoC.displayUserInvalidInputMessage("Please enter a year!");
				}else if(rn.isEmpty()){
					IoC.displayUserInvalidInputMessage("Please specifiy the number of books");
				}else{
					lib.setReportYear(Integer.parseInt(ry));
					lib.setReportNumBooks(Integer.parseInt(rn));
					librarianController.performPopularReportAction();
					reportYearField.setText("");
					numBookField.setText("");
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(reportPopular, c);
		popularPanel.add(reportPopular);
		popularRootPanel.add(popularPanel, BorderLayout.WEST);
		
		//Exit Panel and button
		JButton closeButton = new JButton("Close");
		closeButton.addActionListener(new ActionListener(){
	
			@Override
			public void actionPerformed(ActionEvent e) {
				LibrarianDialog.this.setVisible(false);
				LibrarianDialog.this.dispose();
			}
			
		});
		JPanel exitPanel = new JPanel();
		exitPanel.add(closeButton);
		add(exitPanel, BorderLayout.SOUTH);
		
		//Add the tabs
		tabbedPane.add(addBookRootPanel, "Add Book");
		tabbedPane.add(addBookCopyPanel, "Add Book Copy");
		tabbedPane.add(checkOutRootPanel, "Check Out Report");
		tabbedPane.add(popularRootPanel, "Popular Book Report");
		
		//Finalize and show
		add(tabbedPane, BorderLayout.CENTER);
		pack();
		setResizable(false);
		Point loc = frame.getLocationOnScreen();
		Dimension d = frame.getSize();
		setLocation(loc.x + (d.width - getWidth())/2, loc.y + (d.height - getHeight())/2);
	  	setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	    setVisible(true);
	}
	
	public void clearAddBookFields(){
		callField.setText("");
		isbnField.setText("");
		titleField.setText("");
		authorField.setText("");
		pubField.setText("");
		yearField.setText("");
	}
	
	public void updateCheckoutReport(List<BookCopy> report){
		DefaultListModel model = (DefaultListModel) reportCheckoutList.getModel();
		model.clear();
		for(BookCopy copy : report){
			model.addElement(copy.toString());
		}
	}
	
	public void updatePopularReport(List<Book> report){
		DefaultListModel model = (DefaultListModel) reportPopularList.getModel();
		model.clear();
		for(Book book : report){
			model.addElement(book.toString());
		}
	}

}
